"""Flask 应用工厂"""
import os
from flask import Flask, request
from flask_babel import Babel

from app.config import settings
from app.extensions import init_extensions, babel
from app.exceptions import register_error_handlers
from app.logs import setup_logging, setup_request_logging


def create_app(config_name: str = None) -> Flask:
    """创建Flask应用实例"""
    
    app = Flask(__name__)
    
    # 配置应用
    configure_app(app, config_name)
    
    # 初始化扩展
    init_extensions(app)
    
    # 设置日志
    setup_logging(app)
    setup_request_logging(app)
    
    # 注册异常处理器
    register_error_handlers(app)
    
    # 注册蓝图
    register_blueprints(app)
    
    # 设置国际化
    setup_babel(app)
    
    return app


def configure_app(app: Flask, config_name: str = None) -> None:
    """配置应用"""
    
    # 基础配置
    app.config['SECRET_KEY'] = settings.secret_key
    app.config['DEBUG'] = settings.debug
    
    # 数据库配置
    app.config['SQLALCHEMY_DATABASE_URI'] = settings.database_url
    app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
    
    # JWT配置
    app.config['JWT_SECRET_KEY'] = settings.jwt_secret_key
    app.config['JWT_ACCESS_TOKEN_EXPIRES'] = settings.jwt_access_token_expires
    
    # API文档配置
    app.config['API_TITLE'] = settings.api_title
    app.config['API_VERSION'] = settings.api_version
    app.config['OPENAPI_VERSION'] = settings.openapi_version
    app.config['OPENAPI_URL_PREFIX'] = '/api/docs'
    app.config['OPENAPI_SWAGGER_UI_PATH'] = '/swagger'
    app.config['OPENAPI_SWAGGER_UI_URL'] = 'https://cdn.jsdelivr.net/npm/swagger-ui-dist/'
    app.config['OPENAPI_REDOC_PATH'] = '/redoc'
    app.config['OPENAPI_REDOC_URL'] = 'https://cdn.jsdelivr.net/npm/redoc@2.0.0/bundles/redoc.standalone.js'
    
    # 国际化配置
    app.config['LANGUAGES'] = settings.language_list
    app.config['BABEL_DEFAULT_LOCALE'] = settings.default_language
    app.config['BABEL_DEFAULT_TIMEZONE'] = 'Asia/Shanghai'


def register_blueprints(app: Flask) -> None:
    """注册蓝图"""
    from app.api.v1 import api_v1_bp
    
    app.register_blueprint(api_v1_bp, url_prefix='/api/v1')


def setup_babel(app: Flask) -> None:
    """设置国际化"""
    
    @babel.localeselector
    def get_locale():
        """获取语言环境"""
        # 1. 从请求头获取语言
        if request.headers.get('Accept-Language'):
            return request.accept_languages.best_match(app.config['LANGUAGES'])
        
        # 2. 从查询参数获取语言
        if request.args.get('lang'):
            lang = request.args.get('lang')
            if lang in app.config['LANGUAGES']:
                return lang
        
        # 3. 返回默认语言
        return app.config['BABEL_DEFAULT_LOCALE'] 